#from django.db import models
from django.contrib.gis.db import models
from django.contrib.auth.models import Group, User
import pytz

FINISH_CHOICES = (
    ('Matte', 'Matte'),
    ('Semi-Matte', 'Semi-Matte'),
    ('Specular/Shiny', 'Specular/Shiny'),
)
LIGHT_CHOICES = (
    ('On', 'On'),
    ('Off', 'Off'),
)
DOOR_CHOICES = (
    ('Open', 'Open'),
    ('Closed', 'Closed'),
)
SPACE_TYPE_CHOICES = (
    ('Default', 'Default'),
    ('Open plan with sound masking and intensive computer use', 'Open plan with sound masking and intensive computer use'),
    ('Open plan without sound masking and intensive computer use', 'Open plan without sound masking and intensive computer use'),
    ('Open plan with sound masking and intermittent computer use', 'Open plan with sound masking and intermittent computer use'),
    ('Open plan without sound masking and intermittent computer use', 'Open plan without sound masking and intermittent computer use'),
    ('Private office', 'Private office'),
    ('Conference room', 'Conference room'),
    ('Teleconference room', 'Teleconference room'),
    ('Corridor-Stairs-Restroom', 'Corridor-Stairs-Restroom'),
    ('Lobby-Reception', 'Lobby-Reception'),
    ('Custom1', 'Custom space 1'),
    ('Custom2', 'Custom space 2'),
    ('Custom3', 'Custom space 3'),
    ('Custom4', 'Custom space 4'),
)
ZONE_TYPE_CHOICES = (
    ('Interior', 'Interior'),
    ('Perimeter', 'Perimeter'),
)
BUILDING_TYPE_CHOICES = (
    ('Office', 'Office'),
    ('Hotel', 'Hotel'),
    ('Apartment', 'Apartment'),
    ('Education', 'Education'),
    ('Food Services', 'Food Services'),
    ('Auto Services', 'Auto Services'),
    ('Public Order', 'Public Order'),
    ('Health Care', 'Health Care'),
    ('Retail', 'Retail'),
    ('Assembly', 'Assembly'),
    ('Other', 'Other'),
)
PMP_CATEGORY_CHOICES = (
    ('Energy', 'Energy'),
    ('Water', 'Water'),
    ('Lighting', 'Lighting'),
    ('Acoustics', 'Acoustics'),
    ('Thermal Comfort', 'Thermal Comfort'),
    ('IAQ', 'IAQ'),
)
IEQ_CATEGORY_CHOICES = (
    ('Lighting', 'Lighting'),
    ('Acoustics', 'Acoustics'),
    ('Thermal Comfort', 'Thermal Comfort'),
    ('IAQ', 'IAQ'),
)
SHADE_POSITION_CHOICES = (
    ('Up','Up'),
    ('Down', 'Down'),
    ('Horizontal', 'Horizontal'),
)
ORIENTATION_CHOICES = (
    ('N','N'),
    ('NE','NE'),
    ('E','E'),
    ('SE','SE'),
    ('S','S'),
    ('SW','SW'),
    ('W','W'),
    ('NW','NW'),
    ('C','C'),
)
DEVICE_ORIENTATION_CHOICES = (
    ('Horizontal', 'Horizontal'),
    ('Vertical', 'Vertical'),
)
DEVICE_TYPE_CHOICES = (
    ('Cart', 'Cart'),
    ('Fixed pole', 'Fixed pole'),
    ('ICM', 'ICM'),
    ('Lighting', 'Lighting'),
    ('Acoustics', 'Acoustics'),
    ('Power', 'Power'),
    ('Water flow', 'Water flow'),
    ('Plenum mote', 'Plenum mote'),
    ('IAQ', 'IAQ'),
    ('Other', 'Other'),
)
SENSOR_CATEGORY_CHOICES = (
    ('IRT', 'IRT'),
    ('Thermistor', 'Thermistor'),
    ('Pressure', 'Pressure'),
    ('Mote thermistor', 'Mote thermistor'),
    ('Water flow', 'Water flow'),
    ('Power', 'Power'),
    ('Illuminance', 'Illuminance'),
    ('Sound level', 'Sound level'),
    ('Anemometer', 'Anemometer'),
    ('Globe temperature (pp-ball)', 'Globe temperature (pp-ball)'),
    ('Relative humidity', 'Relative humidity'),
    ('CO2', 'CO2'),
    ('Other', 'Other'),
)
WINDOW_TYPE_CHOICES = (
    ('Fixed', 'Fixed'),
    ('Operable', 'Operable'),
)
WINDOW_WALL_CHOICES = (
    ('0-25%','0-25%'),
    ('26-50%','26-50%'),
    ('51-75%','51-75%'),
    ('76-100%', '76-100%'),
)
FLOOR_TYPE_CHOICES = (
    ('Concrete','Concrete'),
    ('Light weight concrete & steel','Light weight concrete & steel'),
    ('Wood','Wood'),
)
WALL_TYPE_CHOICES = (
    ('Heavy (concrete, stone)','Heavy (concrete, stone)'),
    ('Medium (brick, block)','Medium (brick, block)'),
    ('Light (stucco, wood, steel, glass)','Light (stucco, wood, steel, glass)'),
)
CEILING_TYPE_CHOICES = (
    ('Exposed concrete','Exposed concrete'),
    ('Standard drop','Standard drop'),
    ('Cloud drop','Cloud drop'),
    ('Insulated', 'Insulated'),
)
COMMISSIONING_CHOICES = (
    ('Standard', 'Standard'),
    ('Abbreviated', 'Abbreviated'),
    ('LEED prerequisite', 'LEED prerequisite'),
    ('LEED additional CX', 'LEED additional CX'),
)
LOCATION_CHOICES = (
    ('Central business', 'Central business'),
    ('Other urban', 'Other urban'),
    ('Suburban', 'Suburban'),
    ('Rural', 'Rural'),
)
YES_NO_CHOICES = (
    ('Yes', 'Yes'),
    ('No', 'No'),
)
TENANT_CHOICES = (
    ('Single', 'Single'),
    ('Multi', 'Multi'),
)
LEED_PRODUCT_CHOICES = (
    ('LEED-NC','LEED-NC'),
    ('LEED-EB','LEED-EB'),
    ('LEED-CS','LEED-CS'),
    ('LEED-CI','LEED-CI'),
    ('LEED-ND','LEED-ND'),
    ('LEED-H','LEED-H'),
)
LEED_VERSION_CHOICES = (
    ('Pilot','Pilot'),
    ('1.0','1.0'),
    ('2.0','2.0'),
    ('2.1','2.1'),
    ('2.2','2.2'),
    ('2009','2009'),
    ('4.0','4.0'),
)
LEED_RATING_CHOICES = (
    ('None','None'),
    ('Pending','Pending'),
    ('Certified','Certified'),
    ('Silver','Silver'),
    ('Gold','Gold'),
    ('Platinum','Platinum'),
)
CHART_IMAGE_TYPE_CHOICES = (
    ('User', 'User'),
    ('Map-summary', 'Map-summary'),
)

CONFIG_FILE_CHOICES = (
    ('setpoint', 'setpoint'),
    ('economizer', 'economizer'),
)

class HvacAttribute(models.Model):
    attribute = models.CharField(max_length=100)
    def __unicode__(self):
        return self.attribute

class LightingAttribute(models.Model):
    attribute = models.CharField(max_length=100)
    def __unicode__(self):
        return self.attribute

class EmissionsAttribute(models.Model):
    attribute = models.CharField(max_length=100)
    def __unicode__(self):
        return self.attribute

class EnvelopeAttribute(models.Model):
    attribute = models.CharField(max_length=100)
    def __unicode__(self):
        return self.attribute
    
class Floor(models.Model):
    floor = models.CharField(max_length=10)
    def __unicode__(self):
        return self.floor
    
class ZoneCategory(models.Model):
    pmp_category = models.CharField(max_length=50)
    def __unicode__(self):
        return self.pmp_category

class Project(models.Model):
    group = models.ForeignKey(Group)
    name = models.CharField(max_length=50, help_text='Short project name') #this field is used when setting up and accessing the smap data sources, so it is important
    building = models.CharField(max_length=50)
    location_description = models.CharField(max_length=30, choices=LOCATION_CHOICES, blank=True)
    city = models.CharField(max_length=20, blank=True)
    state = models.CharField(max_length=2, blank=True)
    zipcode = models.CharField(max_length=5, blank=True)
    country = models.CharField(max_length=20, blank=True)
    latitude = models.DecimalField(max_digits=8, decimal_places=5, blank=True, null=True)
    longitude = models.DecimalField(max_digits=8, decimal_places=5, blank=True, null=True)
    timezone = models.CharField(max_length=50, choices=[(x, x) for x in pytz.common_timezones])
    start_date = models.DateField()
    end_date = models.DateField(null=True, blank=True)
    building_type = models.CharField(max_length=20, choices=BUILDING_TYPE_CHOICES, blank=True)
    gross_floor_area = models.PositiveIntegerField(help_text='Non parking', blank=True, null=True)
    conditioned_floors_ag = models.PositiveIntegerField(blank=True, null=True)
    conditioned_floors_bg = models.PositiveIntegerField(blank=True, null=True)
    primary_construction_year = models.PositiveIntegerField(blank=True, null=True)
    secondary_construction_year = models.PositiveIntegerField(blank=True, null=True)
    commissioning_level = models.CharField(max_length=30, choices=COMMISSIONING_CHOICES, blank=True)
    hvac_attributes = models.ManyToManyField(HvacAttribute, blank=True)
    lighting_attributes = models.ManyToManyField(LightingAttribute, blank=True)
    average_flr_flr_height = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
    average_flr_clg_height = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
    primary_window_type = models.CharField(max_length=30, choices=WINDOW_TYPE_CHOICES, blank=True)
    envelope_attributes = models.ManyToManyField(EnvelopeAttribute, blank=True)
    primary_floor_construction = models.CharField(max_length=50, choices=FLOOR_TYPE_CHOICES, blank=True)
    primary_wall_construction = models.CharField(max_length=50, choices=WALL_TYPE_CHOICES, blank=True)
    primary_ceiling_construction = models.CharField(max_length=50, choices=CEILING_TYPE_CHOICES, blank=True)
    window_wall_ratio = models.CharField(max_length=20, choices=WINDOW_WALL_CHOICES, blank=True)
    avg_male_occupants = models.PositiveIntegerField(blank=True, null=True)
    avg_female_occupants = models.PositiveIntegerField(blank=True, null=True)
    #computers = models.PositiveIntegerField(blank=True, null=True)
    notes = models.TextField(blank=True)
    image = models.ImageField(upload_to='pictures', blank=True, null=True)
    mon_fri_start_hour = models.PositiveIntegerField(blank=True, null=True)
    mon_fri_end_hour = models.PositiveIntegerField(blank=True, null=True)
    sat_sun_start_hour = models.PositiveIntegerField(blank=True, null=True)
    sat_sun_end_hour = models.PositiveIntegerField(blank=True, null=True)
    occupied_heating_sp = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    occupied_cooling_sp = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    unoccupied_heating_sp = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    unoccupied_cooling_sp = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    survey_tc = models.PositiveIntegerField(blank=True, null=True)
    survey_lighting = models.PositiveIntegerField(blank=True, null=True)
    survey_acoustics = models.PositiveIntegerField(blank=True, null=True)
    survey_iaq = models.PositiveIntegerField(blank=True, null=True)
    survey_tc_bm = models.PositiveIntegerField(blank=True, null=True)
    survey_lighting_bm = models.PositiveIntegerField(blank=True, null=True)
    survey_acoustics_bm = models.PositiveIntegerField(blank=True, null=True)
    survey_iaq_bm = models.PositiveIntegerField(blank=True, null=True)
    primary_architect = models.CharField(max_length=50, blank=True)
    secondary_architect = models.CharField(max_length=50, blank=True)
    mechanical_engineer = models.CharField(max_length=50, blank=True)
    electrical_engineer = models.CharField(max_length=50, blank=True)
    structural_engineer = models.CharField(max_length=50, blank=True)
    landscape_architect = models.CharField(max_length=50, blank=True)
    general_contractor = models.CharField(max_length=50, blank=True)
    owner = models.CharField(max_length=50, blank=True)
    owner_occupied = models.CharField(max_length=5, choices=YES_NO_CHOICES, blank=True)
    government_occupied = models.CharField(max_length=5, choices=YES_NO_CHOICES, blank=True)
    tenancy = models.CharField(max_length=10, choices=TENANT_CHOICES, blank=True)
    leed_product = models.CharField(max_length=20, choices=LEED_PRODUCT_CHOICES, blank=True)
    leed_version = models.CharField(max_length=10, choices=LEED_VERSION_CHOICES, blank=True)
    leed_rating = models.CharField(max_length=20, choices=LEED_RATING_CHOICES, blank=True)
    emissions_attributes = models.ManyToManyField(EmissionsAttribute, blank=True)
    floors = models.ManyToManyField(Floor,blank=True)
    def __unicode__(self):
        return self.name 

class ChartImage(models.Model):
    project = models.ForeignKey(Project)
    name = models.CharField(max_length=25)
    caption = models.CharField(max_length=140)
    image_url = models.CharField(max_length=100)
    pmp_category = models.CharField(max_length=50, choices=PMP_CATEGORY_CHOICES)
    map_image = models.ImageField(upload_to='pictures', blank=True, null=True)
    type = models.CharField(max_length=30, choices=CHART_IMAGE_TYPE_CHOICES, blank=True)
    legend = models.TextField(blank=True)
    def __unicode__(self):
        return self.name

class IeqModel(models.Model):
    name = models.CharField(max_length=50)
    iaq_weight = models.DecimalField(max_digits=5, decimal_places=4)
    tc_weight = models.DecimalField(max_digits=5, decimal_places=4)
    lghtg_weight = models.DecimalField(max_digits=5, decimal_places=4)
    acc_weight = models.DecimalField(max_digits=5, decimal_places=4)
    def __unicode__(self):
        return self.name 

class IeqSpace(models.Model):
    model = models.ForeignKey(IeqModel)
    space_type = models.CharField(max_length=100, choices=SPACE_TYPE_CHOICES)
    weight = models.DecimalField(max_digits=5, decimal_places=4, blank=True, null=True)
    summer_start_month = models.PositiveIntegerField(blank=True, null=True)
    summer_end_month = models.PositiveIntegerField(blank=True, null=True)
    qc1_tc_summer_condition_low = models.DecimalField(max_digits=6, decimal_places=2)
    qc1_tc_summer_condition_high = models.DecimalField(max_digits=6, decimal_places=2)
    qc1_tc_winter_condition_low = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc1_tc_winter_condition_high = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc1_iaq_condition_low = models.PositiveIntegerField()
    qc1_iaq_condition_high = models.PositiveIntegerField()
    qc1_lighting_condition_low = models.PositiveIntegerField()
    qc1_lighting_condition_high = models.PositiveIntegerField()
    qc1_acc_condition_low = models.PositiveIntegerField()
    qc1_acc_condition_high = models.PositiveIntegerField()
    qc2_tc_summer_condition_low = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc2_tc_summer_condition_high = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc2_tc_winter_condition_low = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc2_tc_winter_condition_high = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc2_iaq_condition_low = models.PositiveIntegerField(blank=True, null=True)
    qc2_iaq_condition_high = models.PositiveIntegerField(blank=True, null=True)
    qc2_lighting_condition_low = models.PositiveIntegerField(blank=True, null=True)
    qc2_lighting_condition_high = models.PositiveIntegerField(blank=True, null=True)
    qc2_acc_condition_low = models.PositiveIntegerField(blank=True, null=True)
    qc2_acc_condition_high = models.PositiveIntegerField(blank=True, null=True)
    qc3_tc_summer_condition_low = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc3_tc_summer_condition_high = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc3_tc_winter_condition_low = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc3_tc_winter_condition_high = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc3_iaq_condition_low = models.PositiveIntegerField(blank=True, null=True)
    qc3_iaq_condition_high = models.PositiveIntegerField(blank=True, null=True)
    qc3_lighting_condition_low = models.PositiveIntegerField(blank=True, null=True)
    qc3_lighting_condition_high = models.PositiveIntegerField(blank=True, null=True)
    qc3_acc_condition_low = models.PositiveIntegerField(blank=True, null=True)
    qc3_acc_condition_high = models.PositiveIntegerField(blank=True, null=True)
    qc4_tc_summer_condition_low = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc4_tc_summer_condition_high = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc4_tc_winter_condition_low = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc4_tc_winter_condition_high = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc4_iaq_condition_low = models.PositiveIntegerField(blank=True, null=True)
    qc4_iaq_condition_high = models.PositiveIntegerField(blank=True, null=True)
    qc4_lighting_condition_low = models.PositiveIntegerField(blank=True, null=True)
    qc4_lighting_condition_high = models.PositiveIntegerField(blank=True, null=True)
    qc4_acc_condition_low = models.PositiveIntegerField(blank=True, null=True)
    qc4_acc_condition_high = models.PositiveIntegerField(blank=True, null=True)
    qc5_tc_summer_condition_low = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc5_tc_summer_condition_high = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc5_tc_winter_condition_low = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc5_tc_winter_condition_high = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    qc5_iaq_condition_low = models.PositiveIntegerField(blank=True, null=True)
    qc5_iaq_condition_high = models.PositiveIntegerField(blank=True, null=True)
    qc5_lighting_condition_low = models.PositiveIntegerField(blank=True, null=True)
    qc5_lighting_condition_high = models.PositiveIntegerField(blank=True, null=True)
    qc5_acc_condition_low = models.PositiveIntegerField(blank=True, null=True)
    qc5_acc_condition_high = models.PositiveIntegerField(blank=True, null=True)
    units_tc = models.CharField(max_length=50, blank=True, default='PPS')
    units_iaq = models.CharField(max_length=50, blank=True, default='ppm above 400')
    units_lighting = models.CharField(max_length=50, blank=True, default='fc')
    units_acc = models.CharField(max_length=50, blank=True, default='dBA')
    def __unicode__(self):
        return self.space_type 
    
class IeqData(models.Model):
    project = models.ForeignKey(Project)
    ieq_space = models.ForeignKey(IeqSpace)
    ieq_category = models.CharField(max_length=50, choices=IEQ_CATEGORY_CHOICES)
    quality_cat1 = models.DecimalField(max_digits=5, decimal_places=2)
    quality_cat2 = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
    quality_cat3 = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
    quality_cat4 = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
    quality_cat5 = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
    def __unicode__(self):
        return 'Space type: ' + str(self.ieq_space) + ', ID: ' + str(self.id)  
    
class ConfigFile(models.Model):
    project = models.ForeignKey(Project)
    name = models.CharField(max_length=50)
    type = models.CharField(max_length=30, choices=CONFIG_FILE_CHOICES)
    def __unicode__(self):
        return self.name  

class Device(models.Model):
    name = models.CharField(max_length=50)
    type = models.CharField(max_length=20, choices=DEVICE_TYPE_CHOICES)
    def __unicode__(self):
        return self.name

class Map(models.Model):
    project = models.ForeignKey(Project)
    floor = models.ForeignKey(Floor)
    left_extent = models.FloatField(blank=True, null=True)
    bottom_extent = models.FloatField(blank=True, null=True)
    right_extent = models.FloatField(blank=True, null=True)
    top_extent = models.FloatField(blank=True, null=True)
    zoom_levels = models.IntegerField(blank=True, null=True)
    resolution = models.IntegerField(blank=True, null=True)
    map_tiler_zip_file = models.FileField(upload_to='maps', blank=True, null=True)
    def __unicode__(self):
        return str(self.project) + '_' + str(self.floor) 

class Zone(models.Model):
    project = models.ForeignKey(Project)
    name = models.CharField(max_length=50)
    floor = models.ForeignKey(Floor, default=1)
    orientation = models.CharField(max_length=3, choices=ORIENTATION_CHOICES)
    space_type = models.CharField(max_length=75, choices=SPACE_TYPE_CHOICES)
    zone_type = models.CharField(max_length=35, choices=ZONE_TYPE_CHOICES)
    #thermostats = models.MultiPointField(blank=True, null=True)
    zone_category = models.ManyToManyField(ZoneCategory, help_text='Limit the measurement categories for which this zone applies.')
    area = models.PositiveIntegerField(blank=True, null=True, help_text='sf')
    ceiling_reflectance = models.PositiveIntegerField(blank=True, null=True, help_text='%')
    nwall_reflectance = models.PositiveIntegerField(blank=True, null=True, help_text='%')
    ewall_reflectance = models.PositiveIntegerField(blank=True, null=True, help_text='%')
    swall_reflectance = models.PositiveIntegerField(blank=True, null=True, help_text='%')
    wwall_reflectance = models.PositiveIntegerField(blank=True, null=True, help_text='%')
    floor_reflectance = models.PositiveIntegerField(blank=True, null=True, help_text='%')
    ceiling_finish = models.CharField(max_length=10, blank=True, choices=FINISH_CHOICES)
    nwall_finish = models.CharField(max_length=10, blank=True, choices=FINISH_CHOICES)
    ewall_finish = models.CharField(max_length=10, blank=True, choices=FINISH_CHOICES)
    swall_finish = models.CharField(max_length=10, blank=True, choices=FINISH_CHOICES)
    wwall_finish = models.CharField(max_length=10, blank=True, choices=FINISH_CHOICES)
    floor_finish = models.CharField(max_length=10, blank=True, choices=FINISH_CHOICES)
    zone_map = models.PolygonField(blank=True, null=True)
    objects = models.GeoManager()
    def __unicode__(self):
        return self.name

class Test(models.Model):
    project = models.ForeignKey(Project)
    device = models.ForeignKey(Device, default=0)
    floor = models.ForeignKey(Floor, default=1)
    start_time = models.DateTimeField()
    end_time = models.DateTimeField(blank=True, null=True)
    location = models.PointField(blank=True, null=True) #this can be null in case you don't want to use maps--then you just define tests at the zone level
    zone = models.ManyToManyField(Zone, blank=True) #the test can be in multiple zones
    device_height = models.DecimalField(max_digits=5, decimal_places=2, default=0, blank=True, null=True, help_text="in.")
    device_orientation = models.CharField(max_length=15, blank=True, choices=DEVICE_ORIENTATION_CHOICES)
    device_angle = models.PositiveIntegerField(blank=True, null=True, help_text="deg.")
    clothing_level = models.DecimalField(max_digits=3, decimal_places=2, blank=True, null=True, help_text="clo")
    metabolic_rate = models.DecimalField(max_digits=3, decimal_places=2, blank=True, null=True, help_text="met")
    shade_position = models.CharField(max_length=15, blank=True, choices=SHADE_POSITION_CHOICES)
    light_status = models.CharField(max_length=7, blank=True, choices=LIGHT_CHOICES)
    door_status = models.CharField(max_length=10, blank=True,choices=DOOR_CHOICES)
    notes = models.TextField(blank=True)  
    objects = models.GeoManager() #required for geodjango/ol-widget
    def __unicode__(self):
        return str(self.id) + ': ' + str(self.start_time)

class AcousticsTest(models.Model):
    test = models.ForeignKey(Test)
    las_eq = models.DecimalField(max_digits=3, decimal_places=1, blank=True, null=True)
    las_min = models.DecimalField(max_digits=3, decimal_places=1, blank=True, null=True)
    las_max = models.DecimalField(max_digits=3, decimal_places=1, blank=True, null=True)
    las_1 = models.DecimalField(max_digits=3, decimal_places=1, blank=True, null=True)
    las_10 = models.DecimalField(max_digits=3, decimal_places=1, blank=True, null=True)
    las_50 = models.DecimalField(max_digits=3, decimal_places=1, blank=True, null=True)
    las_90 = models.DecimalField(max_digits=3, decimal_places=1, blank=True, null=True)
    las_95 = models.DecimalField(max_digits=3, decimal_places=1, blank=True, null=True)
    las_99 = models.DecimalField(max_digits=3, decimal_places=1, blank=True, null=True)
    lcs_eq = models.DecimalField(max_digits=3, decimal_places=1, blank=True, null=True)
    lcs_max = models.DecimalField(max_digits=3, decimal_places=1, blank=True, null=True)
    
class IaqTest(models.Model):
    test = models.ForeignKey(Test)
    co = models.DecimalField(max_digits=5, decimal_places=1, blank=True, null=True)
    pm10 = models.DecimalField(max_digits=5, decimal_places=1, blank=True, null=True)
    pm25 = models.DecimalField(max_digits=5, decimal_places=1, blank=True, null=True)
    tvoc = models.DecimalField(max_digits=5, decimal_places=1, blank=True, null=True)
    
class HdrTest(models.Model):
    test = models.ForeignKey(Test)
    luminance_max = models.DecimalField(max_digits=10, decimal_places=1, blank=True, null=True)
    luminance_avg = models.DecimalField(max_digits=10, decimal_places=1, blank=True, null=True)
    ugr_max = models.DecimalField(max_digits=3, decimal_places=1, blank=True, null=True)
    ugr_avg = models.DecimalField(max_digits=3, decimal_places=1, blank=True, null=True)

class Sensor(models.Model):
    project = models.ForeignKey(Project)
    name = models.CharField(max_length=50, blank=True)
    uuid = models.CharField(max_length=36)
    path = models.CharField(max_length=50)
    sensor_type = models.CharField(max_length=50, choices=SENSOR_CATEGORY_CHOICES, blank=True)
    device = models.ForeignKey(Device, blank=True, null=True)
    sensor_height = models.DecimalField(max_digits=5, decimal_places=2, blank=True, null=True)
    pmp_category = models.CharField(max_length=50, choices=PMP_CATEGORY_CHOICES, blank=True)
    description = models.CharField(max_length=100, blank=True)  
    def __unicode__(self):
        return self.name
